package com.rtx.edi.platform.synctask.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.rtx.api.enums.FieldValidateType;
import com.rtx.api.utils.FieldValidateUtils;
import com.rtx.api.utils.MultipleDataSource;
import com.rtx.common.IdUtils;
import com.rtx.common.JaxbObjectAndXmlUtil;
import com.rtx.edi.model.api.bo.ApiMappingInfoBo;
import com.rtx.edi.model.api.po.PlApiMapping;
import com.rtx.edi.model.api.po.PlApiMappingStructure;
import com.rtx.edi.model.log.po.PlApiRequestContentLog;
import com.rtx.edi.model.log.po.PlApiRequestLog;
import com.rtx.edi.model.qm.RtxQMResponse;
import com.rtx.edi.model.request.SyncRequest;
import com.rtx.edi.model.response.EdiResponse;
import com.rtx.edi.platform.baseinfo.service.PlApiService;
import com.rtx.edi.platform.config.service.PlApiMappingConfigService;
import com.rtx.edi.platform.handler.JsonConvert;
import com.rtx.edi.platform.handler.SqlMappingConvert;
import com.rtx.edi.platform.handler.TargetFieldHandle;
import com.rtx.edi.platform.handler.service.HandleSqlService;
import com.rtx.edi.platform.log.service.PlApiRequestContentLogService;
import com.rtx.edi.platform.log.service.PlApiRequestLogService;
import com.rtx.edi.platform.synctask.handler.PlTaskHandler;
import com.rtx.model.emums.EnumDataType;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * <p>
 * 同步请求 前端控制器
 * </p>
 *
 * @author wq
 * @since 2023-03-19
 */
@SuppressWarnings("all")
@Api(tags = {"同步请求"})
@RestController
@RequestMapping("/v1/api")
public class PlSyncController {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private PlApiService plApiService;

	@Autowired
	private PlApiRequestLogService plApiRequestLogService;

	@Autowired
	private PlApiMappingConfigService plApiMappingConfigService;
	
	@Autowired
	PlApiRequestContentLogService plApiRequestContentLogService;
	
	@Autowired
	HandleSqlService handleSqlService;
	
	@Autowired
	PlTaskHandler plTaskHandler;
	

	/**
	 * 同步请求
	 * @return
	 */
	@ApiOperation(value = "同步请求", notes = "同步请求")
	@PostMapping("syncRequest")
	public String syncRequest(HttpServletRequest request) throws IOException {
		PlApiRequestLog log =new PlApiRequestLog();
		//获取token
		String token = request.getHeader(EnumDataType.AUTHORIZATION.getValue());
		//获取请求体
		String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
		SyncRequest syncRequest = JSON.parseObject(body,SyncRequest.class);
		//验证必填字段
		FieldValidateUtils.fieldNotNull(syncRequest,FieldValidateType.ALL);
		//获取场景映射信息
		ApiMappingInfoBo apiInfo = plApiService.getApiMappingInfo(syncRequest.getCompanyId(),syncRequest.getApiMappingId(),log);
		//获取报文结构
		List<PlApiMappingStructure> structureList = plApiService.getPlApiMappingStructure(syncRequest.getApiMappingId());
		//获取全局变量
		Map<String, Map<String, Object>> globalMap = plApiMappingConfigService.executeSqlByMappingId(syncRequest.getApiMappingId(), JSON.toJSONString(syncRequest.getData()));
		//转化报文结构
//		JsonConvertHandler handler = new JsonConvertHandler(JSON.toJSONString(syncRequest.getData()),structureList,globalMap);
		String requestJson = plApiService.convertJson(structureList,JSON.toJSONString(syncRequest.getData()),globalMap);
		//String requestJson = handler.convertJson();
		//发送请求
		String result = HttpRequest
						.post(apiInfo.getTargetUrl())
						.header(Header.AUTHORIZATION, token)
						.body(requestJson)
						.timeout(30000)
						.execute()
						.body();
		//记录日志
//		plApiRequestLogService.save();
		return result;
	}

	/**
	 * 奇门请求
	 * @return
	 */
	@ApiOperation(value = "奇门请求", notes = "奇门请求")
	@PostMapping("qmRequest")
	public String qmRequest(HttpServletRequest request) throws IOException {
		PlApiRequestLog log =new PlApiRequestLog();
		PlApiRequestContentLog content = new PlApiRequestContentLog();
		String result = null;
		
		try {
			//获取method
			String method = request.getParameter("method");
			String customerid = request.getParameter("customerid");
			String app_key = request.getParameter("app_key");
			//获取请求体
			String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
			log.setRequestData1(body);
			content.setRequestContent(body);
			log.setRequestData2("appkey-"+app_key+"-customerid-"+customerid);
			
			
			logger.info("奇门请求数据：{}",body);
			//转化为JSON
			JSONObject sourceJson = plTaskHandler.getJSONObject(body);
			logger.info("XML转化为JSON结果：{}",sourceJson.toString());
			
			PlApiMapping plApiMapping = plApiService.getPlApiMappingByApiMappingCode(method);
			Assert.notNull(plApiMapping,"对接场景编号：" + method + "不存在");
			//获取场景映射信息
			ApiMappingInfoBo apiInfo = plApiService.getApiMappingInfo(plApiMapping.getCompanyId(),plApiMapping.getId(),log);
			//获取报文结构
			List<PlApiMappingStructure> structureList = plApiService.getPlApiMappingStructure(apiInfo.getApiMappingId());
			//转化报文结构
			JsonConvert convert = new JsonConvert(sourceJson.toString(),apiInfo.getTargetJsonTemplate(),structureList,null);
			convert.convert();
			
			//该方法抛出异常 会切换数据源
			Map<String, Map<String, Object>> globalMap = plApiMappingConfigService.executeSqlByMappingId(apiInfo.getApiMappingId(), convert.getTargetJosn());
			String targetjson = convert.getTargetJosn();
			
			logger.info("转化为目标JSON：{}",targetjson);
			
			log.setRequestData3(targetjson);
			
			String path = StrUtil.replaceLast(apiInfo.getLogkey(),"数组","[]");
			if(path != null){
				String logkey = String.valueOf(sourceJson.getByPath(path));
				log.setLogkey(logkey);
			}
			
			//二次映射
			String targetJosn = mappingTargetJSONByAppKey(method,app_key,convert.getTargetJosn(),log,sourceJson.toString());
			
			//处理字段 配置得转换脚本
			targetjson = TargetFieldHandle.handleFieldScript(targetjson, structureList);
			
			if("table".equals(plApiMapping.getActiveTarget())) {
				
				SqlMappingConvert sqlMappingConvert = new SqlMappingConvert(targetjson,apiInfo.getTargetApi(),globalMap,new ArrayList());
				sqlMappingConvert.convertSql();
				String datasourcekey = sqlMappingConvert.getActiveDataSourcekey();
				MultipleDataSource.setDataSourceKey(datasourcekey);
				List<String> sqlList =  sqlMappingConvert.getTargetSql();
				
				handleSqlService.insertSql(sqlList);
			}else {
				//发送请求
				logger.info("目标请求地址：{}",apiInfo.getTargetUrl());
				result = HttpRequest
						.post(apiInfo.getTargetUrl()+"?customerid="+customerid+"&app_key="+app_key)
						//.header(Header.AUTHORIZATION, token)
						.body(convert.getTargetJosn())
						.timeout(30000)
						.execute()
						.body();
				logger.info("目标请求结果：{}",result);
			}
			log.setRequestData3(result);
			content.setResponseContent(result);
		} catch (Exception e) {
			logger.error("奇门请求异常-",e);
			RtxQMResponse res = new RtxQMResponse();
			res.setFailure(e.getMessage());
			result = JaxbObjectAndXmlUtil.object2Xml(res);
		}
		
		try {
			String logno = IdUtils.simpleUUID();
			//记录日志
			log.setLogNo(logno);
			content.setLogNo(logno);
			
			MultipleDataSource.setDataSourceKey("ris_edi_dev");
			plApiRequestContentLogService.save(content);
			plApiRequestLogService.save(log);
			MultipleDataSource.ClearDataSourceKey();
		} catch (Exception e) {
			logger.error("奇门请求记录日志异常-",e);
		}
		return result;
	}
	
	
	//每个ISV单独逻辑
	private String mappingTargetJSONByAppKey(String method,String appkey,String targetJosnCommon,PlApiRequestLog log,String sourceJson) {
		PlApiMapping plApiMapping = plApiService.getPlApiMappingByApiMappingCode(method+"."+appkey);
		if(plApiMapping == null) {
			return targetJosnCommon;
		}
		ApiMappingInfoBo apiInfo = plApiService.getApiMappingInfo(plApiMapping.getCompanyId(),plApiMapping.getId(),log);
		
		List<PlApiMappingStructure> structureList = plApiService.getPlApiMappingStructure(apiInfo.getApiMappingId());

		//转化报文结构
		JsonConvert convert = new JsonConvert(sourceJson,targetJosnCommon,structureList,null);
		convert.convert();
		return convert.getTargetJosn();
	}
	
	/**
	 * 转化JSON报文
	 * @param request
	 * @return
	 */
	@ApiOperation(value = "转化同结构JSON", notes = "转化同结构JSON报文")
	@PostMapping("convertJson")
	public EdiResponse convertJson(@RequestBody SyncRequest request) {
		//获取报文结构
		List<PlApiMappingStructure> structureList = plApiService.getPlApiMappingStructure(request.getApiMappingId());
		String json = plApiService.convertSameStructureJson(request,structureList);
		return EdiResponse.success().data("result",json);
	}
}